/*
 * Class handles the business logic for DVD search functions.
 */
package com.cheapflix.business;

import com.cheapflix.beans.DVD;
import com.cheapflix.beans.SearchCriteria;
import com.cheapflix.dao.DVDDao;
import java.util.List;
import org.apache.log4j.Logger;

/**
 * Facade class for the various Flick search functionality.
 * @author Group B
 */
public class SearchManager {

    private static final Logger logger = Logger.getLogger(SearchManager.class);

    private static final int MAX_RESULTS = 10;

    private DVDDao dvdDao;

    public SearchManager(DVDDao dao) {
        this.dvdDao = dao;
    }

    /**
     * Based on any basic search term returns a SearchCriteria bean.
     * @param basicSearch - search term
     * @param criteria - Search parameters.
     * @return A new SearchCriteria with the search results.
     */
    public SearchCriteria search(String basicSearch,
            final SearchCriteria criteria) {
        if (criteria.getBasicSearch().equalsIgnoreCase(basicSearch)) {
            return criteria;
        } else {
            SearchCriteria retCriteria = new SearchCriteria();
            retCriteria.setBasicSearch(basicSearch);
            List<DVD> list = this.dvdDao.findDvds(basicSearch);
            if (list == null) {
                retCriteria.setStartIndex(0);
                retCriteria.setEndIndex(0);
            } else {
                retCriteria.setDvds(list);
                retCriteria.setStartIndex(0);
                if (list.size() > MAX_RESULTS) {
                    retCriteria.setEndIndex(MAX_RESULTS - 1);
                } else {
                    retCriteria.setEndIndex(list.size() - 1);
                }
            }
            return retCriteria;
        }
    }

    /**
     * Finds the next 10 search results of an existing search.
     * @param criteria - current search criteria
     * @return SearchCriteria bean with updated results.
     */
    public SearchCriteria searchNext(final SearchCriteria criteria) {
        SearchCriteria retCriteria = new SearchCriteria();
        retCriteria.setBasicSearch(criteria.getBasicSearch());
        retCriteria.setDvds(criteria.getDvds());
        if (criteria.getDvds().size() > criteria.getEndIndex() + MAX_RESULTS) {
            retCriteria.setEndIndex(criteria.getEndIndex() + MAX_RESULTS);
            retCriteria.setStartIndex(criteria.getStartIndex() + MAX_RESULTS);
        } else {
            retCriteria.setEndIndex(criteria.getDvds().size() - 1);
            retCriteria.setStartIndex(criteria.getEndIndex() + 1);
        }
        return retCriteria;
    }

    /**
     * Finds the previous 10 search results of an existing search.
     * @param criteria - current search criteria
     * @return SearchCriteria bean with updated results.
     */
    public SearchCriteria searchPrev(final SearchCriteria criteria) {
        SearchCriteria retCriteria = new SearchCriteria();
        retCriteria.setBasicSearch(criteria.getBasicSearch());
        retCriteria.setDvds(criteria.getDvds());
        if (0 >= criteria.getStartIndex() - MAX_RESULTS) {
            retCriteria.setEndIndex(criteria.getStartIndex() - 1);
            retCriteria.setStartIndex(0);
        } else {
            retCriteria.setEndIndex(criteria.getStartIndex() - 1);
            retCriteria.setStartIndex(criteria.getStartIndex() - MAX_RESULTS);
        }
        return retCriteria;
    }

    /**
     * Searches for a DVD with specific search terms.
     * @param title - DVD title search term
     * @param actors - DVD actors search term
     * @param director - DVD director search term
     * @param genre - DVD genre search terms
     * @param criteria - Current SearchCriteria bean
     * @return - New SearchCriteria bean with search results.
     */
    public SearchCriteria advancedSearch(String title, String actors,
            String director, String genre, final SearchCriteria criteria) {

        SearchCriteria retCriteria = new SearchCriteria();
        retCriteria.setBasicSearch("");
        retCriteria.setTitle(title);
        retCriteria.setActors(actors);
        retCriteria.setGenre(genre);
        retCriteria.setDirector(director);
        List<DVD> list = this.dvdDao.findDvds(title, genre, actors, director);
        if (list == null) {
            retCriteria.setStartIndex(0);
            retCriteria.setEndIndex(0);
        } else {
            retCriteria.setDvds(list);
            retCriteria.setStartIndex(0);
            if (list.size() > MAX_RESULTS) {
                retCriteria.setEndIndex(MAX_RESULTS - 1);
            } else {
                retCriteria.setEndIndex(list.size() - 1);
            }
        }
        return retCriteria;
    }

    /**
     * Finds a DVD based on the DVD id
     * @param id - DVD id
     * @return The DVD with the matching ID.
     */
    public DVD searchId(int id) {
        return this.dvdDao.getDVD(id);
    }

}
